/*
 * Draw.cpp
 *
 * Copyright (c) 2009-2011 [BRN] aka. SWW13.
 *
 * This file is part of [BRN]Lib.
 *
 * [BRN]Lib is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * [BRN]Lib is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with [BRN]Lib.  If not, see <http ://www.gnu.org/licenses/>.
 */

#if !defined BRNlib_NoD3D
#include "Draw.h"

namespace BRNlib
{
	namespace D3D
	{
		namespace Core
		{
			void Draw::Rectangle(D3DXDevice *pD3Ddev, int x, int y, int w, int h, D3DCOLOR Color)
			{
				//Set Rec
				D3DRECT Rectangle = {x, y, x+w, y+h};

				//Draw Lines
				pD3Ddev->Clear(1, &Rectangle, D3DCLEAR_TARGET, Color, 0,  0);
			}

			void Draw::TransparentRectangle(D3DXDevice *pD3Ddev, int x, int y, int w, int h, int Alpha, D3DCOLOR Color)
			{
				#if defined BRNlib_D3D9
					D3DXVECTOR2 vLine[2];
					ID3DXLine* pLine;
					D3DXCreateLine(pD3Ddev, &pLine);

					if(pLine)
					{
						pLine->SetWidth((float)w);
						pLine->SetAntialias(false);
						pLine->SetGLLines(true);

						vLine[0].x = (float)x + w/2;
						vLine[0].y = (float)y;
						vLine[1].x = (float)x + w/2;
						vLine[1].y = (float)y + h;

						pLine->Begin();
						pLine->Draw(vLine, 2, D3DCOLOR_RGBA( Color::GetRed(Color), Color::GetGreen(Color), Color::GetBlue(Color), 255-int(Alpha*2.55) ) );

						pLine->End();
						pLine->Release();
					}
				#endif

				#if defined BRNlib_D3D8
					Rectangle(pD3Ddev, x, y, w, h, Color);
				#endif
			}

			void Draw::Box(D3DXDevice *pD3Ddev, int x, int y, int w, int h, int Size, D3DCOLOR Color)
			{
				//Set Lines
				D3DRECT Left	= {x, y, x+Size, y+h};
				D3DRECT Right	= {x+w, y, x+w+Size, y+h};
				D3DRECT Top		= {x, y, x+w, y+Size};
				D3DRECT Buttom	= {x, y+h, x+w+Size, y+h+Size};

				//Draw Lines
				pD3Ddev->Clear(1, &Left, D3DCLEAR_TARGET, Color, 0,  0);
				pD3Ddev->Clear(1, &Right, D3DCLEAR_TARGET, Color, 0,  0);
				pD3Ddev->Clear(1, &Top, D3DCLEAR_TARGET, Color, 0,  0);
				pD3Ddev->Clear(1, &Buttom, D3DCLEAR_TARGET, Color, 0,  0);
			}

			void Draw::Object(D3DXDevice *pD3Ddev, int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2, D3DCOLOR Color)
			{
				LPDIRECT3DVERTEXBUFFER9 pVertexObject = NULL;
				void *pVertexBuffer = NULL;
				struct D3DVERTEX {float x, y, z, rhw; DWORD color;} vertices[3];
				vertices[0].z = 0.0f;
				vertices[0].rhw = 1.0f;
				vertices[0].color = Color;
				vertices[1].z = 0.0f;
				vertices[1].rhw = 1.0f; 
				vertices[1].color = Color;
				vertices[2].z = 0.0f;
				vertices[2].rhw = 1.0f; 
				vertices[2].color = Color;

				DWORD DrawMode_BackUp = D3DFILL_SOLID;
				pD3Ddev->GetRenderState(D3DRS_FILLMODE, &DrawMode_BackUp);

				if(FAILED(pD3Ddev->CreateVertexBuffer(3*sizeof(D3DVERTEX), 0, D3DFVF_XYZRHW|D3DFVF_DIFFUSE, D3DPOOL_DEFAULT, &pVertexObject, NULL)))
					return;
				if(FAILED(pVertexObject->Lock(0, 3*sizeof(D3DVERTEX), &pVertexBuffer, 0)))
					return;
				pD3Ddev->SetStreamSource(0, pVertexObject, 0, sizeof(D3DVERTEX));
				pD3Ddev->SetFVF(D3DFVF_XYZRHW|D3DFVF_DIFFUSE);
				pD3Ddev->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);

				//---------------------------------------------------
				//---------------------------------------------------
				//Back Triangle left
				vertices[0].x = x2;
				vertices[0].y = y2;

				vertices[1].x = x2+w2;
				vertices[1].y = y2;

				vertices[2].x = x2;
				vertices[2].y = y2+h2;

				memcpy(pVertexBuffer, vertices, 3*sizeof(D3DVERTEX));				
				pD3Ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
				
				//Back Triangle right
				vertices[0].x = x2+w2;
				vertices[0].y = y2;

				vertices[1].x = x2+w2;
				vertices[1].y = y2+h2;

				vertices[2].x = x2;
				vertices[2].y = y2+h2;

				memcpy(pVertexBuffer, vertices, 3*sizeof(D3DVERTEX));				
				pD3Ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
				//---------------------------------------------------
				//---------------------------------------------------
				
				//---------------------------------------------------
				//---------------------------------------------------
				//Down Triangle left
				vertices[0].x = x1;
				vertices[0].y = y1+h1;

				vertices[1].x = x2;
				vertices[1].y = y2+h2;

				vertices[2].x = x2+w2;
				vertices[2].y = y2+h2;

				memcpy(pVertexBuffer, vertices, 3*sizeof(D3DVERTEX));				
				pD3Ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
				
				//Down Triangle right
				vertices[0].x = x1;
				vertices[0].y = y1+h1;

				vertices[1].x = x2+w2;
				vertices[1].y = y2+h2;

				vertices[2].x = x1+w1;
				vertices[2].y = y1+h1;

				memcpy(pVertexBuffer, vertices, 3*sizeof(D3DVERTEX));				
				pD3Ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
				//---------------------------------------------------
				//---------------------------------------------------

				//---------------------------------------------------
				//---------------------------------------------------
				//Left Triangle left
				vertices[0].x = x1;
				vertices[0].y = y1;

				vertices[1].x = x2;
				vertices[1].y = y2+h2;

				vertices[2].x = x1;
				vertices[2].y = y1+h1;

				memcpy(pVertexBuffer, vertices, 3*sizeof(D3DVERTEX));				
				pD3Ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
				
				//Left Triangle right
				vertices[0].x = x2;
				vertices[0].y = y2;

				vertices[1].x = x2;
				vertices[1].y = y2+h2;

				vertices[2].x = x1;
				vertices[2].y = y1;

				memcpy(pVertexBuffer, vertices, 3*sizeof(D3DVERTEX));				
				pD3Ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
				//---------------------------------------------------
				//---------------------------------------------------

				//---------------------------------------------------
				//---------------------------------------------------
				//Right Triangle left
				vertices[0].x = x1+w1;
				vertices[0].y = y1;

				vertices[1].x = x2+w2;
				vertices[1].y = y2+h2;

				vertices[2].x = x1+w1;
				vertices[2].y = y1+h1;

				memcpy(pVertexBuffer, vertices, 3*sizeof(D3DVERTEX));				
				pD3Ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
				
				//Right Triangle right
				vertices[0].x = x1+w1;
				vertices[0].y = y1;

				vertices[1].x = x2+w2;
				vertices[1].y = y2;

				vertices[2].x = x2+w2;
				vertices[2].y = y2+h2;

				memcpy(pVertexBuffer, vertices, 3*sizeof(D3DVERTEX));				
				pD3Ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
				//---------------------------------------------------
				//---------------------------------------------------

				//---------------------------------------------------
				//---------------------------------------------------
				//Up Triangle left
				vertices[0].x = x1;
				vertices[0].y = y1;

				vertices[1].x = x2;
				vertices[1].y = y2;

				vertices[2].x = x2+w2;
				vertices[2].y = y2;

				memcpy(pVertexBuffer, vertices, 3*sizeof(D3DVERTEX));				
				pD3Ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
				
				//Up Triangle right
				vertices[0].x = x1;
				vertices[0].y = y1;

				vertices[1].x = x2+w2;
				vertices[1].y = y2;

				vertices[2].x = x1+w1;
				vertices[2].y = y1;

				memcpy(pVertexBuffer, vertices, 3*sizeof(D3DVERTEX));				
				pD3Ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
				//---------------------------------------------------				
				//---------------------------------------------------

				//---------------------------------------------------
				//---------------------------------------------------
				//Front Triangle left
				vertices[0].x = x1;
				vertices[0].y = y1;

				vertices[1].x = x1+w1;
				vertices[1].y = y1;

				vertices[2].x = x1;
				vertices[2].y = y1+h1;

				memcpy(pVertexBuffer, vertices, 3*sizeof(D3DVERTEX));				
				pD3Ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
				
				//Front Triangle right
				vertices[0].x = x1+w1;
				vertices[0].y = y1;

				vertices[1].x = x1+w1;
				vertices[1].y = y1+h1;

				vertices[2].x = x1;
				vertices[2].y = y1+h1;

				memcpy(pVertexBuffer, vertices, 3*sizeof(D3DVERTEX));				
				pD3Ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
				//---------------------------------------------------
				//---------------------------------------------------

				pVertexObject->Unlock();
				pD3Ddev->SetRenderState(D3DRS_FILLMODE, DrawMode_BackUp);
			}
			void Draw::Cube(D3DXDevice *pD3Ddev, int x, int y, int size, D3DCOLOR Color)
			{
				int Move = sqrt((double)size * size / 2) / 2;

				Draw::Object(pD3Ddev, x, y, size, size, x+Move, y-Move, size, size, Color);
			}
			void Draw::CubeEx(D3DXDevice *pD3Ddev, int x, int y, int w, int h, D3DCOLOR Color)
			{
				int Move = sqrt((double)h * w / 2) / 2;

				Draw::Object(pD3Ddev, x, y, w, h, x+Move, y-Move, w, h, Color);
			}
			void Draw::CubeEx(D3DXDevice *pD3Ddev, int x1, int y1, int x2, int y2, int w, int h, D3DCOLOR Color)
			{
				Draw::Object(pD3Ddev, x1, y1, w, h, x2, y2, w, h, Color);
			}

			void Draw::SimpleCrosshair(D3DXDevice *pD3Ddev, int Length, int Size, D3DCOLOR Color)
			{
				int ScreenCenterX = D3D::Core::Screen::GetCenter(pD3Ddev).x;
				int ScreenCenterY = D3D::Core::Screen::GetCenter(pD3Ddev).y;
				int SizeLeft = Size/2 > 0 ? Size/2 : 1;
				int SizeRight = Size/2;

				D3DRECT RecX = {ScreenCenterX-Length, ScreenCenterY-SizeLeft, ScreenCenterX+Length, ScreenCenterY+SizeRight};
				D3DRECT RecY = {ScreenCenterX-SizeLeft, ScreenCenterY-Length, ScreenCenterX+SizeRight, ScreenCenterY+Length};
				                        
				pD3Ddev->Clear(1, &RecX, D3DCLEAR_TARGET, Color, 0,  0);
				pD3Ddev->Clear(1, &RecY, D3DCLEAR_TARGET, Color, 0,  0);
			}

			void Draw::Crosshair(D3DXDevice *pD3Ddev, int Length, int Size, D3DCOLOR Color)
			{
				int ScreenCenterX = D3D::Core::Screen::GetCenter(pD3Ddev).x;
				int ScreenCenterY = D3D::Core::Screen::GetCenter(pD3Ddev).y;
				int SizeLeft = Size/2 > 0 ? Size/2 : 1;
				int SizeRight = Size/2;

				D3DRECT RecX  = {ScreenCenterX-Length, ScreenCenterY-SizeLeft, ScreenCenterX-long(Length*0.2), ScreenCenterY+SizeRight};
				D3DRECT RecX2 = {ScreenCenterX+long(Length*0.2), ScreenCenterY-SizeLeft, ScreenCenterX+Length, ScreenCenterY+SizeRight};
				D3DRECT RecY  = {ScreenCenterX-SizeLeft, ScreenCenterY-Length, ScreenCenterX+SizeRight, ScreenCenterY-long(Length*0.2)};
				D3DRECT RecY2 = {ScreenCenterX-SizeLeft, ScreenCenterY+long(Length*0.2), ScreenCenterX+SizeRight, ScreenCenterY+Length};
				D3DRECT Dot = {ScreenCenterX-SizeLeft, ScreenCenterY-SizeLeft, ScreenCenterX+SizeRight, ScreenCenterY+SizeRight};
				                        
				pD3Ddev->Clear(1, &RecX,  D3DCLEAR_TARGET, Color, 0,  0);
				pD3Ddev->Clear(1, &RecX2, D3DCLEAR_TARGET, Color, 0,  0);
				pD3Ddev->Clear(1, &RecY,  D3DCLEAR_TARGET, Color, 0,  0);				
				pD3Ddev->Clear(1, &RecY2, D3DCLEAR_TARGET, Color, 0,  0);
				pD3Ddev->Clear(1, &Dot, D3DCLEAR_TARGET, Color, 0,  0);
			}
		}
	}
}

#endif